/*
 * Copyright (c) 2015. 石头哥哥
 */

package com.comom.manager.kit.security;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;


/**
 * 加密工具类
 */
public class SecurityUtil {

    private static final String DES_MODE = "DES/CBC/PKCS5Padding";
    private static final String AES_MODE = "AES/CBC/PKCS5Padding";

//	private static byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 };

    /**
     * 格式化des的key，只能为8位
     *
     * @param key
     * @return
     */
    private static String formateDesKey(String key) {
        if (key == null) {
            key = "";
        }
        if (key.length() != 8) {
            key = (key + "wgbox123oop9p89k").substring(0, 8);
        }
        return key;
    }

    /**
     * 格式化des的key，只能为16位
     *
     * @param key
     * @return
     */
    private static String formateAesKey(String key) {
        if (key == null) {
            key = "";
        }
        if (key.length() != 16) {
            key = (key + "wgbox123oop9p89k").substring(0, 16);
        }
        return key;
    }

    /**
     * 进行DES加密，加密模式cbc，填充模式PKCS5Padding，返回结果为Base64格式字符串。密钥必须为8位，若不是8位，程序自动调整为8位
     * 。加密失败，返回null
     *
     * @param input
     * @param strKey
     * @return
     */
    public static String desEncrypt(String input, String strKey) {
        String result = null;
        result = getString(getEncDESByte(input, strKey));
        // Cipher cipher;
        // try {
        // cipher = Cipher.getInstance(DES_MODE);
        // cipher.init(Cipher.ENCRYPT_MODE, getKey(strKey));
        // result = getString(cipher.doFinal(input.getBytes("utf-8")));
        // }
        // catch(Exception e) {
        // e.printStackTrace();
        // }
        return result;
    }

    /**
     * 进行DES加密，返回结果字节组。密钥必须为8位，若不是8位，程序自动调整为8位。加密失败，返回null
     *
     * @param input
     * @param strKey
     * @return
     */
    private static byte[] getEncDESByte(String input, String strKey) {
        // LogUtil.d("开始对字符串进行MD5:" + input);
        byte[] result = null;
        Cipher cipher;

        try {
            strKey = formateDesKey(strKey);
            byte[] iv = strKey.getBytes();
            IvParameterSpec zeroIv = new IvParameterSpec(iv);
            SecretKeySpec key = new SecretKeySpec(strKey.getBytes(), "DES");

            cipher = Cipher.getInstance(DES_MODE);
            cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
            result = (cipher.doFinal(input.getBytes("utf-8")));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 进行DES解密，返回结果为普通字符串。密钥必须为8位，若不是8位，程序自动调整为8位。解密失败，返回null
     *
     * @param input
     * @param strKey
     * @return
     */
    @SuppressWarnings("ConstantConditions")
    public static String desDecrypt(String input, String strKey) {
        String result = null;
        Cipher cipher;
        try {
            cipher = Cipher.getInstance(DES_MODE);
            strKey = formateDesKey(strKey);
            byte[] iv = strKey.getBytes();
            IvParameterSpec zeroIv = new IvParameterSpec(iv);
            SecretKeySpec key = new SecretKeySpec(strKey.getBytes(), "DES");
            cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
            byte[] data = cipher.doFinal(getByte(input));
            result = new String(data, "utf-8");

        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 分配密钥
     *
     * @param content
     * @return
     */
    private static final String passowrd = "geekisme";

    /**
     * @param input
     * @return
     */
    public static String desDecrypt(String input) {
        return desDecrypt(input, passowrd);
    }

    public static String desEncrypt(String content) {
        return desEncrypt(content, passowrd);
    }

    /**
     * @param input
     * @return
     */
    public static String aesDecrypt(String input) {
        return aesDecrypt(input, passowrd);
    }

    public static String aesEncrypt(String content) {
        return aesEncrypt(content, passowrd);
    }

    /**
     * 进行128位的AES加密，返回结果为base64字符串。加密失败，返回null
     *
     * @param content 需要加密的内容
     * @param strKey  加密密码
     * @return
     */
    public static String aesEncrypt(String content, String strKey) {
        String result = null;
        try {
            strKey = formateAesKey(strKey);
//			KeyGenerator kgen = KeyGenerator.getInstance("AES");
//			kgen.init(128, new SecureRandom(strKey.getBytes()));
//			SecretKey secretKey = kgen.generateKey();


//			 IvParameterSpec zeroIv = new IvParameterSpec(strKey.getBytes());  
            SecretKeySpec secretKey = new SecretKeySpec(strKey.getBytes(), "AES");

            byte[] enCodeFormat = secretKey.getEncoded();
            byte[] iv = strKey.getBytes();
            IvParameterSpec zeroIv = new IvParameterSpec(iv);
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance(AES_MODE);// 创建密码器
            byte[] byteContent = content.getBytes("utf-8");
            cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);// 初始化
            byte[] data = cipher.doFinal(byteContent);
            result = getString(data); // 加密
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 进行128位的AES解密，返回结果为普通字符串。解密失败，返回null
     *
     * @param input    待解密内容
     * @param password 解密密钥
     * @return
     */
    public static String aesDecrypt(String input, String password) {
        String result = null;
        try {
            password = formateAesKey(password);
            byte[] content = getByte(input);
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(password.getBytes()));
//			SecretKey secretKey = kgen.generateKey();
            SecretKeySpec secretKey = new SecretKeySpec(password.getBytes(), "AES");

            byte[] enCodeFormat = secretKey.getEncoded();
            byte[] iv = password.getBytes();
            IvParameterSpec zeroIv = new IvParameterSpec(iv);
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance(AES_MODE);// 创建密码器
            cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);// 初始化
            byte[] data = cipher.doFinal(content);
            result = new String(data, "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 进行128位的AES解密，返回结果为普通字符串。解密失败，返回null
     *
     * @param input    待解密内容
     * @param password 解密密钥
     * @return
     */
    public static String aesDecrypt(String input, String password, String def) {
        String result = def;
        try {
            password = formateAesKey(password);
            byte[] content = getByte(input);
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(password.getBytes()));
//			SecretKey secretKey = kgen.generateKey();
            SecretKeySpec secretKey = new SecretKeySpec(password.getBytes(), "AES");

            byte[] enCodeFormat = secretKey.getEncoded();
            byte[] iv = password.getBytes();
            IvParameterSpec zeroIv = new IvParameterSpec(iv);
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance(AES_MODE);// 创建密码器
            cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);// 初始化
            byte[] data = cipher.doFinal(content);
            result = new String(data, "utf-8");
        } catch (Exception e) {
        }
        return result;
    }


    /**
     * 加密
     *
     * @param publicKey
     * @param srcBytes
     * @return
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    protected byte[] rsaEncrypt(RSAPublicKey publicKey, byte[] srcBytes) {
        try {
            if (publicKey != null) {
                //Cipher负责完成加密或解密工作，基于RSA
                Cipher cipher = Cipher.getInstance("RSA");
                //根据公钥，对Cipher对象进行初始化
                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
                byte[] resultBytes = cipher.doFinal(srcBytes);
                return resultBytes;
            }
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解密
     *
     * @param privateKey
     * @param srcBytes
     * @return
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    protected byte[] rsaDecrypt(RSAPrivateKey privateKey, byte[] srcBytes) {
        try {
            if (privateKey != null) {
                //Cipher负责完成加密或解密工作，基于RSA
                Cipher cipher = Cipher.getInstance("RSA");
                //根据公钥，对Cipher对象进行初始化
                cipher.init(Cipher.DECRYPT_MODE, privateKey);
                byte[] resultBytes = cipher.doFinal(srcBytes);
                return resultBytes;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String getString(byte[] data) {
        return Base64.encode(data, 0, data.length);
    }

    public static byte[] getByte(String data) {
        try {
            return Base64.decode(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
//        String encode = SecurityUtil.desEncrypt("111111", "**geekisme**");
//        System.out.println("des encode:"+encode);
//        String decrypt = SecurityUtil.desDecrypt(encode);
//        System.out.println("des decode:"+decrypt);
        String url="com.mysql.jdbc.Driver";
//        String encode=SecurityUtil.desEncrypt(url);
//        System.out.println(encode);
        System.out.println(SecurityUtil.desDecrypt("cFSZ9h9eApRRW6Gy7sTB4A==")  );
    }

}
